package ase.eleitweg.server;

import java.rmi.*;
import ase.eleitweg.common.*;
import ase.eleitweg.common.fail.InconsistentDataException;
import com.google.inject.*;
import java.util.*;

@ImplementedBy(RunController.class)
public interface RunManager extends Remote {

	/**
	 * Creates a new instance (run) of a workflow wf with user u
	 * 
	 * @param wf
	 *            A Workflow to be used - all IDs (of nodes and edges) must !=0
	 * @param u
	 *            A User who has started the run. This user must be member of
	 *            the group wf.getStartNode().getGroup() and have ID!=0
	 * @throws RemoteException
	 */
	public Run createRun(Workflow wf, User u) throws RemoteException;
	
	public Run createRun(Workflow wf, User u, String runDesc) throws RemoteException;

	/**
	 * Takes a runnig instance (run) and moves to the next node using the edge e
	 * @param i A started instance
	 * @param e Edge selected by the user. It must be one of the outgoing edges of the node i.getNode().getCondition().getEdges().
	 * @throws RemoteException
	 */
	public void moveOn(Run i, Edge e) throws RemoteException;
	
	public void acceptRun(Run r, User u) throws RemoteException, InconsistentDataException;

	/**
	 * Registers client for updates. If any of the runs and workflow changes, ch will get a callback
	 * @param ch
	 * @throws RemoteException
	 */
	public void registerClient(ClientHandle ch) throws RemoteException;

	/**
	 * Removes client from notification list. After calling this function, you will get no update()-callbacks.
	 * @param ch
	 * @throws RemoteException
	 */
	public void unregisterClient(ClientHandle ch) throws RemoteException;

	/**
	 * Returns all documents associated with the run r. 
	 * @param r a started run
	 * @return A list of Documents. Be aware, that this might return a list of more megabytes or even larger!
	 * @throws RemoteException
	 */
	public List<Document> getDocuments(Run r) throws RemoteException;

	/**
	 * Returns all started runs which are currently at the user u
	 * @param u
	 * @return
	 * @throws RemoteException
	 */
	public List<Run> getMyRuns(User u) throws RemoteException;
	
	public List<Run> getAcceptableRuns(User u) throws RemoteException;

	/**
	 * Returns all workflow, which are startable by user u - this means, that user u is member of the workflow.getStartnode().getGroup()
	 * @param u
	 * @return
	 * @throws RemoteException
	 */
	public List<Workflow> getStartableWF(User u) throws RemoteException;

	/**
	 * Returns a list of all started (and not finished) runs
	 * @return
	 * @throws RemoteException
	 */
	public List<Run> startedRun() throws RemoteException;

	/**
	 * Returns a list of runs that have reached the end-node.
	 * @return
	 * @throws RemoteException
	 */
	public List<Run> getFinishedRuns() throws RemoteException;
	
	public void uploadDocuments(Run r, List<Document> docs) throws RemoteException;
	
	public List<Document> getHollowDocuments(int runid)  throws RemoteException;
	
	public void unacceptRun(Run r) throws RemoteException;
	
	public void removeRun(Run r) throws RemoteException;

}
